﻿using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell.Interop;
using VSXtra;
using IServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider;

namespace AndreySmirnov.BLToolkitUtils.VSPackage
{
	[ComVisible(true)]
	public class BLTHierarchyRoot : IVsUIHierarchy
	{
		private const int S_OK = VSConstants.S_OK;
		private const int E_FAIL = VSConstants.E_FAIL;
		private IServiceProvider m_serviceProvider;
		private ImageHandler m_imageHandler = new ImageHandler();

		public BLTHierarchyRoot()
		{
			m_imageHandler.AddImage(Resources.RootNodeIcon);
		}

		public int SetSite(IServiceProvider psp)
		{
			m_serviceProvider = psp;
			
			return VSConstants.S_OK;
		}

		public int GetSite(out IServiceProvider ppSP)
		{
			ppSP = m_serviceProvider;
			return ppSP == null ? E_FAIL : S_OK;
		}

		public int QueryClose(out int pfCanClose)
		{
			pfCanClose = 1;
			return S_OK;
		}

		public int Close()
		{
			return S_OK;
		}

		public int GetGuidProperty(uint itemid, int propid, out Guid pguid)
		{
			pguid = Guid.Empty;
			return E_FAIL;
		}

		public int SetGuidProperty(uint itemid, int propid, ref Guid rguid)
		{
			return E_FAIL;
		}

		public int GetProperty(uint itemid, int propid, out object pvar)
		{
			pvar = null;
			var prop = (__VSHPROPID) propid;
			if (itemid != VSConstants.VSITEMID_ROOT)
				return E_FAIL;
			switch (prop)
			{
				case __VSHPROPID.VSHPROPID_Caption:
					pvar = "Tables";
					return S_OK;
				case __VSHPROPID.VSHPROPID_IconImgList:
					pvar = m_imageHandler.ImageList.Handle;
					return S_OK;
				case __VSHPROPID.VSHPROPID_IconIndex:
					pvar = 0;
					return S_OK;
			}
			return E_FAIL;
		}

		public int SetProperty(uint itemid, int propid, object var)
		{
			return E_FAIL;
		}

		public int GetNestedHierarchy(uint itemid, ref Guid iidHierarchyNested, out IntPtr ppHierarchyNested, out uint pitemidNested)
		{
			ppHierarchyNested = IntPtr.Zero;
			pitemidNested = 0;
			return E_FAIL;
		}

		public int GetCanonicalName(uint itemid, out string pbstrName)
		{
			pbstrName = null;
			return E_FAIL;
		}

		public int ParseCanonicalName(string pszName, out uint pitemid)
		{
			pitemid = 0;
			return E_FAIL;
		}

		private readonly List<IVsHierarchyEvents> m_eventsList = new List<IVsHierarchyEvents>();

		public int AdviseHierarchyEvents(IVsHierarchyEvents pEventSink, out uint pdwCookie)
		{
			pdwCookie = (uint) (m_eventsList.Count + 1);
			m_eventsList.Add(pEventSink);
			return S_OK;
		}

		public int UnadviseHierarchyEvents(uint dwCookie)
		{
			if (m_eventsList.Count < dwCookie)
				return E_FAIL;
			var index = dwCookie - 1;
			m_eventsList.RemoveAt((int) index);
			return S_OK;
		}

		#region Unused methods

		public int Unused0()
		{
			throw new NotImplementedException();
		}

		public int Unused1()
		{
			throw new NotImplementedException();
		}

		public int Unused2()
		{
			throw new NotImplementedException();
		}

		public int Unused3()
		{
			throw new NotImplementedException();
		}

		public int Unused4()
		{
			throw new NotImplementedException();
		}

		#endregion


		public int QueryStatusCommand(uint itemid, ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
		{
			return E_FAIL;
		}

		public int ExecCommand(uint itemid, ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
		{
			return E_FAIL;
		}
	}
}